package cs4game;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;

public class World {

	public Map<Vector3D, Integer> allBlocks = new TreeMap<Vector3D, Integer>();
	public Set<Vector3D> indestructibleBs = new HashSet<Vector3D>();
	public Map<Vector3D, Integer> allBlocksCopy = new TreeMap<Vector3D, Integer>();
	public ArrayList<MobEntity> allEntities = new ArrayList<MobEntity>();
	public ArrayList<MobEntity> allEntitiesCopy = new ArrayList<MobEntity>();
	private boolean movingEntities = false;
	private Player player;
	
	public static Texture tex;
	public World(){
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_DECAL);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		try {
			tex = TextureLoader.getTexture("PNG", new FileInputStream("./terrain.png"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		tex.bind();
	}

	public void drawAll(){
		tex.bind();
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		for(Vector3D p: allBlocks.keySet()){
			int block = allBlocks.get(p);
			int id = getID(block);

			//System.out.println(BlockDefs.get(id));
			
			BlockID def = BlockDefs.get(id);
			def.draw(p,  block, this);
		}
		
		for(MobEntity e: allEntities){
			e.draw();
		}
	}
	
	public void addBlock(Vector3D p, int id){
		allBlocksCopy.put(p, id);
	}
	public int getBlock(Vector3D p){
		if(allBlocks.get(p)==null)
			return -1;
		return allBlocks.get(p);
	}
	
	public void addEntity(MobEntity e){
		if(!getMovingEntities()){
			allEntities.add(e);
		}
		allEntitiesCopy.add(e);
	}
	public void removeEntity(MobEntity e){
		if(!getMovingEntities()){
			allEntities.remove(e);
		}
		allEntitiesCopy.remove(e);
	}

	public int getID(int block){return (block & 0xFFF00000)>>52;}

	@SuppressWarnings("unchecked")
	public void moveEntities(float delta) {
		movingEntities=true;
		for(MobEntity each: allEntities){
			each.move(delta);
		}
		movingEntities=false;
		allEntities = (ArrayList<MobEntity>) allEntitiesCopy.clone();
	}

	public boolean getMovingEntities() {
		return movingEntities ;
	}

	public void removeBlock(Vector3D p) {
		allBlocksCopy.remove(p);
	}
	
	public void updateAllBlocks(){
		allBlocks = allBlocksCopy;
		allBlocksCopy = new TreeMap<Vector3D, Integer>();
		for(Vector3D p: allBlocks.keySet()){
			allBlocksCopy.put(p, allBlocks.get(p));		
		}
	}
	
	public void addPlayer(Player p){
		player = p;
		addEntity(p);
	}

	public Player getPlayer() {
		// TODO Auto-generated method stub
		return player;
	}


}
